package offerbook;


import baseclass.f_hash.Code04_IsLands;

/**
 * 请设计一个函数，用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。
 * 路径可以从矩阵中的任意一个格子开始，每一步可以在矩阵中向左，向右，向上，向下移动一个格子。
 * 如果一条路径经过了矩阵中的某一个格子，则该路径不能再进入该格子。
 * 例如
 * a b c e
 * s f c s
 * a d e e
 * 矩阵中包含一条字符串"bcced"的路径，
 * 但是矩阵中不包含"abcb"路径，因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后，
 * 路径不能再次进入该格子。
 * <p>
 * 思路见孤岛问题，{@link Code04_IsLands}
 */
public class Code66_HasPathInMatrix {
    public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
        if (matrix == null || rows <= 0 || cols <= 0 || str == null || str.length == 0)
            return false;
        //default all false
        boolean[] visited = new boolean[matrix.length];
        for (int i = 0; i < matrix.length; i++) {
            if (doHasPath(matrix, rows, cols, i, str, 0, visited)) {
                return true;
            }

        }
        return false;

    }

    private boolean doHasPath(char[] matrix, int rows, int cols, int i,
                              char[] str, int index, boolean[] visited) {
        //base case 1
        if (index == str.length) return true;
        //base case 2
        if (i <= 0 || i >= matrix.length) return false;
        //如果满足相等并且没有访问过
        if (str[index] == matrix[i] && !visited[i]) {
            //标记访问
            visited[i] = true;
            //前后左右访问
            boolean res =
                //上，当前位置是i，上的话就是 i - cols
                doHasPath(matrix, rows, cols, i - cols, str, index + 1, visited) ||
                //下
                doHasPath(matrix, rows, cols, i + cols, str, index + 1, visited) ||
                //左
                doHasPath(matrix, rows, cols, i - 1, str, index + 1, visited) ||
                //右
                doHasPath(matrix, rows, cols, i + 1, str, index + 1, visited);
            //如果当前路径不同，记得还原visited标记
            if(!res)
                visited[i] = false;
            return  res;

        } else {
            return false;
        }

    }
}
